#pragma once
#include"Common.hpp"
#include"EventLoop.hpp"
class LoopThread
{
private:
    std::thread _thread;
    std::mutex _mtx;
    EventLoop *_loop;
    std::condition_variable _con;

private:
    void ThreadLoopEntry()
    {
        EventLoop loop;
        {
            std::unique_lock<std::mutex> lock(_mtx);
            _loop = &loop;
            _con.notify_all();
        }
        loop.Start();
    }

public:
    LoopThread() : _thread(std::bind(&LoopThread::ThreadLoopEntry, this)), _loop(nullptr)
    {
    }
    EventLoop *GetEventLoopPtr()
    {
        EventLoop *loop = nullptr;
        {
            std::unique_lock<std::mutex> lock(_mtx);
            // if (_loop == nullptr)   // 这里不能加判断的，因为在这里的逻辑是一定要执行loop=_loop的逻辑的
            // 如果说_loop不为空，return loop，而loop是空的，因为没有进if 执行loop=_loop
            // {
                _con.wait(lock, [&]()
                          { return _loop != nullptr; });
                loop = _loop;
            // }
        }
        return loop;
    }
};
class LoopThreadPool
{
private:
    int _thread_nums; // 多少个线程 ?
    int _index;       // 分配出去的eventLoop的指针数组下标
    EventLoop *_base_loop;
    std::vector<LoopThread *> _threads;
    std::vector<EventLoop *> _loops;

public:
    LoopThreadPool(EventLoop *baseloop)
        : _base_loop(baseloop),
          _thread_nums(0),
          _index(0)
    {
    }
    void SetThreadNums(int num)
    {
        _thread_nums = num;
    }
    // 初始化并创建threadpool
    void Init()
    {
        if (_thread_nums > 0)
        {
            _threads.resize(_thread_nums);
            _loops.resize(_thread_nums);
            for (int i = 0; i < _thread_nums; i++)
            {
                _threads[i] = new LoopThread();
                _loops[i] = _threads[i]->GetEventLoopPtr();
            }
        }
        return;
    }
    // 分配eventLoop
    EventLoop *Dispatch()
    {
        if (_thread_nums == 0)
        {
             return _base_loop;
        }
        _index = (_index + 1) % _thread_nums;
        LOG(DEBUG, "为线程%u分配的EventLoop为: %p,_index = %d\n",std::this_thread::get_id(),_loops[_index], _index);
        return _loops[_index];
    }
};
